﻿// Copyright (c) 2012 Mokah Nnamezie & Andrew Cooper
// Neo4Net graph database - http://neo4net.codeplex.com
//
// This file is part of Neo4Net - a .Net port of the Neo4j graph database
//
// Neo4Net is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

namespace Neo4Net.Kernel.Impl.Core
{
    using Neo4Net.GraphDb;
    using NUnit.Framework;

    [TestFixture]
    public class TestNeo4NetApiExceptions : AbstractNeo4NetTestCase
    {
        [Test]
        public void TestNotInTransactionException()
        {
            INode node1 = GraphDb.CreateNode();
            node1.SetProperty("test", 1);
            INode node2 = GraphDb.CreateNode();
            INode node3 = GraphDb.CreateNode();
            IRelationship rel = node1.CreateRelationshipTo(node2, MyRelTypes.Test);
            rel.SetProperty("test", 11);
            Commit();

            // Create node with no transaction should throw exception
            Assert.That(() => GraphDb.CreateNode(), Throws.TypeOf<NotInTransactionException>());

            // Create relationship with no transaction should throw exception
            Assert.That(() => node1.CreateRelationshipTo(node2, MyRelTypes.Test), Throws.TypeOf<NotInTransactionException>());

            // Set property with no transaction should throw exception
            Assert.That(() => node1.SetProperty("test", 2), Throws.TypeOf<NotInTransactionException>());

            // Set property with no transaction should throw exception
            Assert.That(() => rel.SetProperty("test", 22), Throws.TypeOf<NotInTransactionException>());

            // Delete node with no transaction should throw exception
            Assert.That(() => node3.Delete(), Throws.TypeOf<NotInTransactionException>());

            // Delete relationship with no transaction should throw exception
            Assert.That(() => rel.Delete(), Throws.TypeOf<NotInTransactionException>());

            NewTransaction();
            Assert.That(node1.GetProperty("test"), Is.EqualTo(1));
            Assert.That(rel.GetProperty("test"), Is.EqualTo(11));
            Assert.That(node1.GetSingleRelationship(MyRelTypes.Test, Direction.Outgoing), Is.EqualTo(rel));
            node1.Delete();
            node2.Delete();
            rel.Delete();
            node3.Delete();
        }

        [Test]
        public void TestNotFoundException()
        {
            INode node1 = GraphDb.CreateNode();
            INode node2 = GraphDb.CreateNode();
            IRelationship rel = node1.CreateRelationshipTo(node2, MyRelTypes.Test);
            long nodeId = node1.Id;
            long relId = rel.Id;
            rel.Delete();
            node2.Delete();
            node1.Delete();
            NewTransaction();

            // Get node by id on deleted node should throw exception
            Assert.That(() => GraphDb.GetNodeById(nodeId), Throws.TypeOf<NotFoundException>()); ;

            // Get relationship by id on deleted node should throw exception
            Assert.That(() => GraphDb.GetRelationshipById(relId), Throws.TypeOf<NotFoundException>()); ;
        }
    }
}
